package com.atguigu.gmall.item.service.impl;

import com.atguigu.gmall.common.bean.ResponseVo;
import com.atguigu.gmall.item.feign.GmallPmsClient;
import com.atguigu.gmall.item.feign.GmallSmsClient;
import com.atguigu.gmall.item.feign.GmallWmsClient;
import com.atguigu.gmall.item.service.ItemService;
import com.atguigu.gmall.item.vo.ItemVo;
import com.atguigu.gmall.pms.entity.*;
import com.atguigu.gmall.pms.vo.ItemAttrGroupVo;
import com.atguigu.gmall.pms.vo.ItemSaleAttrValuesVo;
import com.atguigu.gmall.sms.vo.ItemSaleVo;
import io.jsonwebtoken.lang.Collections;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import org.thymeleaf.context.IContext;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ItemServiceImpl implements ItemService {
    @Autowired
    GmallPmsClient pmsClient;
    @Autowired
    GmallSmsClient smsClient;
    @Autowired
    GmallWmsClient wmsClient;
    @Autowired
    ExecutorService executorService;
    @Autowired
    TemplateEngine templateEngine;
    //thymeleaf 异步 持久化 静态化页面
    public void asyncCreateHtml(Long skuId){
        executorService.execute(()->{
            try {
                //process参数1：模板文件名称(默认会使用thymeleaf的前缀和后缀)
                //process参数2：上下文对象(用来携带 模板页面需要的thymeleaf的属性值)
                Context ctx = new Context();
                ctx.setVariable("itemVo" , this.queryItemBySkuId(skuId));
                //process参数3：输出流(根据模板页面生成的静态化页面保存的文件位置)
                Writer writer = new PrintWriter(new File("F:\\html\\"+skuId+".html"));
                templateEngine.process("item" , ctx , writer );
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                log.warn("skuId:{} 的静态化商品详情页失败"  , skuId);
            }
        });
    }
    @Override
    public ItemVo queryItemBySkuId(Long skuId) {
        ItemVo itemVo = new ItemVo();
//        1、先使用skuid查询sku对象：可以得到sku的数据，品牌id，第3级分类的id，spuid (已有接口)
        CompletableFuture<SkuEntity> skuEntityCompletableFuture = CompletableFuture.supplyAsync(() -> {
            ResponseVo<SkuEntity> skuEntityResponseVo = pmsClient.querySkuById(skuId);
            SkuEntity skuEntity = skuEntityResponseVo.getData();
            if (skuEntity == null) {
                return null;
            }
            //将查询到的skuEntity对象的属性值设置给itemVo对象：
            itemVo.setPrice(skuEntity.getPrice());
            itemVo.setBrandId(skuEntity.getBrandId());
            itemVo.setTitle(skuEntity.getTitle());
            itemVo.setSubTitle(skuEntity.getSubtitle());
            itemVo.setDefaultImage(skuEntity.getDefaultImage());
            itemVo.setWeight(skuEntity.getWeight());
            Long spuId = skuEntity.getSpuId();
            itemVo.setSpuId(spuId);
            itemVo.setSkuId(skuId.toString());
            return skuEntity;
        },executorService);


        //        2、使用三级分类id查询三级分类 和1,2级分类： 自定义接口   依赖于任务1的结果
        CompletableFuture<Void> categoryCompletableFuture = skuEntityCompletableFuture.thenAcceptAsync(skuEntity -> {
            //        skuEntity.getCategoryId()
            ResponseVo<List<CategoryEntity>> queryItemLevel123CatesByC3id = pmsClient.queryItemLevel123CatesByC3id(skuEntity.getCategoryId());
            List<CategoryEntity> categoryEntities = queryItemLevel123CatesByC3id.getData();
            if (!Collections.isEmpty(categoryEntities)) {
                itemVo.setCategories(categoryEntities);
            }
        },executorService);


        //        3、使用品牌id查询品牌对象：(已有接口) 依赖1的结果
        CompletableFuture<Void> brandCompletableFuture = skuEntityCompletableFuture.thenAcceptAsync(skuEntity -> {
            ResponseVo<BrandEntity> brandEntityResponseVo = pmsClient.queryBrandById(skuEntity.getBrandId());
            BrandEntity brandEntity = brandEntityResponseVo.getData();
            if (brandEntity != null) {
                itemVo.setBrandName(brandEntity.getName());
            }
        },executorService);

        //                4、使用spuid查询spu对象：(已有接口)  依赖1的结果
        CompletableFuture<Void> spuEntityCompletableFuture = skuEntityCompletableFuture.thenAcceptAsync(skuEntity -> {
            ResponseVo<SpuEntity> spuEntityResponseVo = pmsClient.querySpuById(skuEntity.getSpuId());
            SpuEntity spuEntity = spuEntityResponseVo.getData();
            if (spuEntity != null) {
                itemVo.setSpuName(spuEntity.getName());
            }
        },executorService);

        //                5、使用skuid查询它的图片对象集合：自定义接口
        CompletableFuture<Void> skuImagesCompletableFuture = CompletableFuture.runAsync(() -> {
            ResponseVo<List<SkuImagesEntity>> queryItemSkuImagesBySkuId = pmsClient.queryItemSkuImagesBySkuId(skuId);
            List<SkuImagesEntity> skuImagesEntities = queryItemSkuImagesBySkuId.getData();
            if (!Collections.isEmpty(skuImagesEntities)) {
                itemVo.setImages(skuImagesEntities);
            }
        },executorService);

        //        6、使用skuid在wms中查询是否有库存：自定义接口
        CompletableFuture<Void> storeCompletableFuture = CompletableFuture.runAsync(() ->{
            ResponseVo<Boolean> booleanResponseVo = wmsClient.queryItemSkuStoreBySkuId(skuId);
            Boolean store = booleanResponseVo.getData();
            if(store!=null){
                itemVo.setStore(store);
            }
        },executorService);

        //        11、使用spuid查询spudesc 详情图片集合：自定义接口
        CompletableFuture<Void> spuDescCompletableFuture = skuEntityCompletableFuture.thenAcceptAsync(skuEntity -> {
            //spuid 就是 spuDesc表的主键，可以当做主键值查询
            ResponseVo<SpuDescEntity> spuDescEntityResponseVo = pmsClient.querySpuDescById(skuEntity.getSpuId());
            SpuDescEntity spuDescEntity = spuDescEntityResponseVo.getData();
            // spuid   http://1.jpg,http://2.jpg
            if (spuDescEntity != null && StringUtils.isNotBlank(spuDescEntity.getDecript())) {
                String[] split = spuDescEntity.getDecript().split(",");
                itemVo.setSpuImages(Arrays.asList(split));
            }
        },executorService);

        //        7、使用skuid在sms中查询 营销数据(促销)： 自定义接口
        CompletableFuture<Void> salesCompletableFuture = CompletableFuture.runAsync(() ->{
            // [{ type:'满减' , desc: '满xxx减xxx' } ,{}]
            ResponseVo<List<ItemSaleVo>> queryItemSalesBySkuId = smsClient.queryItemSalesBySkuId(skuId);
            List<ItemSaleVo> itemSaleVos = queryItemSalesBySkuId.getData();
            if(!Collections.isEmpty(itemSaleVos)){
                itemVo.setSales(itemSaleVos);
            }
        },executorService);


        //        8、使用spuid查询它所有sku集合的 销售属性和值集合的 数据：自定义接口
        CompletableFuture<Void> skusAttrValuesCompletableFuture = skuEntityCompletableFuture.thenAcceptAsync(skuEntity ->{
            // spuid:  使用sku表 根据spuid查询它所有的sku的id集合，使用skuid联查sku_attr_value
            // [{attrId: 3 ,attrName:'机身颜色' , attrValues:['黑色' , '白色'] }]   sku_attr_value表中的数据
            ResponseVo<List<ItemSaleAttrValuesVo>> queryItemSkuAttrValuesBySpuId =
                    pmsClient.queryItemSkuAttrValuesBySpuId(skuEntity.getSpuId());
            List<ItemSaleAttrValuesVo> itemSaleAttrValuesVos = queryItemSkuAttrValuesBySpuId.getData();
            if(!Collections.isEmpty(itemSaleAttrValuesVos)){
                itemVo.setSaleAttrs(itemSaleAttrValuesVos);
            }
        },executorService);

        //        9、使用skuid查询它的销售属性id  和值的映射map：自定义接口
        CompletableFuture<Void> skuAttrValueCompletableFuture = CompletableFuture.runAsync(() -> {
            // { 3: '黑色' , 4： '8G'  }
            ResponseVo<Map<Long, String>> queryItemSkuAttrValueBySkuId = pmsClient.queryItemSkuAttrValueBySkuId(skuId);
            Map<Long, String> skuAttrValueBySkuIdData = queryItemSkuAttrValueBySkuId.getData();
            if (!Collections.isEmpty(skuAttrValueBySkuIdData)) {
                itemVo.setSaleAttr(skuAttrValueBySkuIdData);
            }
        },executorService);

        //        10、使用spuid查询所有的sku的销售属性值拼接字符串 和 skuid的映射：自定义接口
        CompletableFuture<Void> skuJsonsCompletableFuture = skuEntityCompletableFuture.thenAcceptAsync(skuEntity -> {
            // {'白色,8G,128G': 1 , '白色,8G,256G':2 }
            ResponseVo<String> stringResponseVo = pmsClient.queryItemSaleJsonsBySpuId(skuEntity.getSpuId());
            String jsons = stringResponseVo.getData();
            if (StringUtils.isNotBlank(jsons)) {
                itemVo.setSkuJsons(jsons);
            }
        },executorService);

        //        12、使用spuid查询 spu的属性组 和属性对象(属性和属性值)：自定义接口
        CompletableFuture<Void> spuAttrsCompletableFuture = skuEntityCompletableFuture.thenAcceptAsync(skuEntity -> {
            ResponseVo<List<ItemAttrGroupVo>> queryItemAttrGroupsBySpuId = pmsClient.queryItemAttrGroupsBySpuId(skuEntity.getSpuId());
            List<ItemAttrGroupVo> itemAttrGroupVos = queryItemAttrGroupsBySpuId.getData();
            if (!Collections.isEmpty(itemAttrGroupVos)) {
                itemVo.setGroups(itemAttrGroupVos);
            }
        },executorService);

        CompletableFuture.allOf(skuEntityCompletableFuture ,
                categoryCompletableFuture,
                brandCompletableFuture,
                spuEntityCompletableFuture,
                skuImagesCompletableFuture,
                storeCompletableFuture,
                spuDescCompletableFuture,
                salesCompletableFuture,
                skusAttrValuesCompletableFuture,
                skuAttrValueCompletableFuture,
                skuJsonsCompletableFuture,
                spuAttrsCompletableFuture
                ).join(); //get阻塞执行结束 继续执行下一行代码，join所以的子线程执行结束才执行处理请求的线程
        //不调用get的原因，返回itemVo对象时 线程还未结束，就算异步任务仍有未结束的 它还会继续执行，
        return itemVo;
    }
}
